package com.luxuewen.sxa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.luxuewen.sxa.common.enums.ResponseEnum;
import com.luxuewen.sxa.common.exception.ApiException;
import com.luxuewen.sxa.entity.*;
import com.luxuewen.sxa.interceptor.JwtInterceptor;
import com.luxuewen.sxa.service.SxaMenusService;
import com.luxuewen.sxa.mapper.SxaMenusMapper;
import com.luxuewen.sxa.service.SxaRoleApisService;
import com.luxuewen.sxa.utils.JwtUtils;
import com.luxuewen.sxa.utils.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wen
 * @description 针对表【sxa_menus】的数据库操作Service实现
 * @createDate 2023-11-11 14:44:01
 */
@Service
public class SxaMenusServiceImpl extends ServiceImpl<SxaMenusMapper, SxaMenus>
        implements SxaMenusService{
    @Autowired
    private CommonServiceImpl commonService;

    @Autowired
    private SxaApisServiceImpl sxaApisService;

    @Autowired
    private SxaRoleMenusServiceImpl sxaRoleMenusService;

    @Autowired
    private SxaRoleApisServiceImpl sxaRoleApisService;

    public List<Map<String, Object>> myList () {
        Map<String, Object> userInfos = JwtInterceptor.getLoginUser();

        boolean apiAuthFlag = false;
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> roles = (List<Map<String, Object>>) userInfos.get("roles");
        for (Map<String, Object> role : roles) {
            if (Objects.equals(role.get("alias").toString(), "super_administrator")) {
                apiAuthFlag = true;
                break;
            }
        }

        if (apiAuthFlag) {
            return saTreeWrapper();
        }
        return myTreeWrapper();
    }

    /**
     * 菜单管理列表（包含按钮）
     * @return
     */
    public List<Map<String, Object>> treeWrapper () {
        QueryWrapper<SxaMenus> sxaMenusQueryWrapper = new QueryWrapper<>();
        sxaMenusQueryWrapper.orderByAsc("sort");

        return tree(sxaMenusQueryWrapper);
    }

    /**
     * 超级管理员个人菜单
     * @return
     */
    public List<Map<String, Object>> saTreeWrapper () {
        QueryWrapper<SxaMenus> sxaMenusQueryWrapper = new QueryWrapper<>();
        sxaMenusQueryWrapper.eq("type", 1).orderByAsc("sort");

        return tree(sxaMenusQueryWrapper);
    }

    public List<String> myButtonAuth () {
        Map<String, Object> userInfos = JwtInterceptor.getLoginUser();
        Integer userId = (Integer) userInfos.get("id");

        QueryWrapper<SxaMenus> sxaMenusQueryWrapper = new QueryWrapper<>();
        sxaMenusQueryWrapper.eq("type", 4)
                .inSql("id", "SELECT menu_id FROM sxa_role_menus WHERE role_id in ( SELECT role_id FROM sxa_user_roles WHERE user_id="+userId+")")
                .select("name")
                .orderByAsc("sort");

        List<Map<String, Object>> btnList = this.listMaps(sxaMenusQueryWrapper);

        return btnList.stream().map(item -> {
            return item.get("name").toString();
        }).toList();
    }

    /**
     * 各角色个人菜单
     * @return
     */
    public List<Map<String, Object>> myTreeWrapper () {
        Map<String, Object> userInfos = JwtInterceptor.getLoginUser();
        Integer userId = (Integer) userInfos.get("id");

        QueryWrapper<SxaMenus> sxaMenusQueryWrapper = new QueryWrapper<>();
        sxaMenusQueryWrapper.eq("type", 1)
                .inSql("id", "SELECT menu_id FROM sxa_role_menus WHERE role_id in ( SELECT role_id FROM sxa_user_roles WHERE user_id="+userId+")")
                .orderByAsc("sort");

        return tree(sxaMenusQueryWrapper);
    }

    public List<Integer> myRoleList (Integer roleId) {
        QueryWrapper<SxaRoleMenus> sxaRoleMenusQueryWrapper = new QueryWrapper<>();
        sxaRoleMenusQueryWrapper.eq("role_id", roleId).select("menu_id");
        List<Map<String, Object>> sxaRoleMenus = sxaRoleMenusService.listMaps(sxaRoleMenusQueryWrapper);

        return sxaRoleMenus.stream().map(it->{
            return (Integer)it.get("menu_id");
        }).collect(Collectors.toList());
    }

    public List<Map<String, Object>> tree (QueryWrapper<SxaMenus> sxaMenusQueryWrapper) {
        List<Map<String, Object>> menus = this.listMaps(sxaMenusQueryWrapper);
        List<Map<String, Object>> all = new ArrayList<>();
        List<Map<String, Object>> data = new ArrayList<>();
        if (!menus.isEmpty()) {
            // 首先获取根节点
            for (Map<String, Object> parent : menus) {
                Map<String, Object> temp = new HashMap<>();
                temp.put("id", parent.get("id"));
                temp.put("sort", parent.get("sort"));
                temp.put("parent_id", parent.get("parent_id"));
                temp.put("name", parent.get("name"));
                temp.put("path", parent.get("path"));
                temp.put("redirect", parent.get("redirect"));
                temp.put("component", parent.get("component"));

                Map<String, Object> meta = new HashMap<>();
                meta.put("title", parent.get("title"));
                meta.put("icon", parent.get("icon"));
                meta.put("type", parent.get("type"));
                meta.put("color", parent.get("color"));
                meta.put("hidden", parent.get("is_hidden"));
                meta.put("fullpage", parent.get("is_fullpage"));
                meta.put("hiddenBreadcrumb", parent.get("is_breadcrumb"));
                if (Objects.equals(parent.get("path").toString(), "/dashboard")) {
                    meta.put("affix", true);
                }

                temp.put("meta", meta);

                all.add(temp);
                if (parent.get("parent_id").equals(0)) {
                    data.add(temp);
                }
            }

            // 存在根节点
            if (!data.isEmpty()) {
                // 获取子节点
                menus = commonService.tree(all, data);
            }
        }
        return menus;
    }

    @Transactional
    public boolean update (SxaMenus sxaMenus) {
        try {
            QueryWrapper<SxaMenus> sxaMenusQueryWrapper = new QueryWrapper<>();
            sxaMenusQueryWrapper.eq("name", sxaMenus.getName()).ne("id", sxaMenus.getId());
            boolean ex = this.exists(sxaMenusQueryWrapper);
            if (ex) {
                throw new Exception("菜单别名已存在，请更换后再试！");
            }

            boolean res = this.updateById(sxaMenus);
            if (!res) {
                throw new Exception("菜单更新失败！");
            }

            // 获取绑定当前菜单的角色
            QueryWrapper<SxaRoleMenus> sxaRoleMenusQueryWrapper = new QueryWrapper<>();
            sxaRoleMenusQueryWrapper.eq("menu_id", sxaMenus.getId()).select("role_id");
            List<SxaRoleMenus> sxaRoleMenusList = sxaRoleMenusService.list(sxaRoleMenusQueryWrapper);
            List<Integer> roleIds = sxaRoleMenusList.stream().map(sxaRoleMenus -> {
                return sxaRoleMenus.getRoleId();
            }).toList();

            List<SxaRoleApis> sxaRoleApisList = new ArrayList<>();
            for (SxaApis api : sxaMenus.getApiList()) {
                if (api.getId() != null) {
                    QueryWrapper<SxaApis> sxaApisQueryWrapper = new QueryWrapper<>();
                    sxaApisQueryWrapper.eq("menu_id", api.getMenuId()).eq("id", api.getId());
                    boolean apiEx = sxaApisService.exists(sxaApisQueryWrapper);
                    if (apiEx) {
                        boolean apiRes = sxaApisService.update(api, sxaApisQueryWrapper);
                        if (!apiRes) {
                            throw new Exception("接口【"+api.getName()+"】："+api.getAlias()+"更新失败！");
                        }
                    } else {
                        throw new Exception("未在菜单中找到接口【"+api.getName()+"】："+api.getAlias()+"，请刷新后再试！");
                    }
                } else {
                    boolean apiRes = sxaApisService.save(api);
                    if (!apiRes) {
                        throw new Exception("接口【"+api.getName()+"】："+api.getAlias()+"保存失败！");
                    }

                    if (!roleIds.isEmpty()) {
                        for (Integer roleId : roleIds) {
                            SxaRoleApis sxaRoleApis = new SxaRoleApis();
                            sxaRoleApis.setRoleId(roleId);
                            sxaRoleApis.setApiId(api.getId());
                            sxaRoleApisList.add(sxaRoleApis);
                        }
                    }
                }
            }

            // 新增的接口继承菜单/按钮
            if (!sxaRoleApisList.isEmpty()) {
                boolean roleApiRes = sxaRoleApisService.saveBatch(sxaRoleApisList);
                if (!roleApiRes) {
                    throw new Exception("新增的接口权限继承失败！");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new ApiException(ResponseEnum.FAILURE.getCode(), e.getMessage());
        }

        return true;
    }
}




